#pragma once
#include "Direction.h"
#include "FieldResource.h"
#include <deque>
#include "DevelopmentCard.h"
#include "ResourceCard.h"
#include "BoardItems.h"
#include "PlayerFactory.h"
#include "BoardItems.h"

namespace catan
{
	class BoardFactory
	{
	public:
		BoardFactory(void);
		~BoardFactory(void);
		Handle<Board> Create4Board();
		void RecyleBoard(Handle<Board> board);
		template <class Type>
		Handle<Type> ToHandle(Type* type)
		{
			return mBoard->mBoardItems->ToHandle(type);
		}
	private:
		void Connect4Field(Fields& fields);
		void CreateNoConnectBuildPoints(Fields& fields);
		void AddBuildPoints(Board& board);
		void ConnectEachField(Handle<Field> lhs, Handle<Field> rhs, FieldDirection::Enum fieldDirection);
		void CreatePorts(Handle<Board> board);
		void CreatePort(Handle<Board> board, int fieldNum, BuildPointDirection::Enum buildPointDirection, FieldResourceType::Enum defaultResource);
		void ConnectPort2BuildPoint(Handle<BuildPoint> buildPoint, Handle<Port> port);
		void CreateNoconnectBuildPoint(Handle<Field> field);
		void CreatePlayers();
		void GetBuildPointDirection(const FieldDirection::Enum fieldDirection, BuildPointDirection::Enum buildPointDirection[2]);
		void Sync2BuildPoint(Handle<BuildPoint>& lhs, Handle<BuildPoint>& rhs, Handle<Field> lField, Handle<Field> rField);
		void RandomFieldResource(Handle<Board> board);
		void MakeFieldBoard(Handle<Board> board);
		void MakeDieNums(Handle<Board> board);
		void AddDieNum(Handle<Board> board, int num);
		void RandomDevelopmentCard(Handle<Board> board);
		void CreateDevelopmentCard(Handle<Board> board,DevelopmentCardType::Enum type, int num);
		void TraceFieldBoard(Handle<Board> board, Handle<Field> field, FieldDirection::Enum lastDirection, int resourceNum, std::deque<Handle<FieldDieNum>>& dieNums, std::map<int, bool>& useFields );
		void CreateResourceCards(Handle<Board> board);
		void CreateResourceCard(Handle<Board> board, ResourceType::Enum type, int num);
		
		void AddFieldResource(Handle<Board> board, FieldResourceType::Enum, int num);

		
		int mFiledsNum;

		template< class _Ty>
		void RecycleVectors(_Ty& tys);

		template< class _Ty>
		void Recycle(_Ty*& ty);
		Handle<Board> mBoard;

		PlayerFactory mPlayerFactory;
	};

	template< class _Ty>
	void BoardFactory::Recycle( _Ty*& ty )
	{
		if (ty)
		{
			delete ty;
			ty = 0;
		}
	}

	template< class _Ty>
	void BoardFactory::RecycleVectors( _Ty& ty )
	{
		for (typename _Ty::iterator it(ty.begin());
			it != ty.end(); ++it)
		{
			if((*it))
			{
				delete *it;
				*it = 0;
			}
		}
		ty.clear();
	}
}	
